home *** CD-ROM | disk | FTP | other *** search
/ Nothing but Tetris / Nothing but Tetris.iso / amiga / wbtris_1.3 / source / wbtris.c.pp / wbtris.c
C/C++ Source or Header  |  2000-01-01  |  48KB  |  1,489 lines

  1. /*
  2.    *******************************************************************************
  3.    *                                                                             *
  4.    *                                                                             *
  5.    *     WW            WW  BBBBBBBB  TTTTTTTTTT  RRRRRRRR   II     SSSSSSS       *
  6.    *     WW            WW  BB     BB     TT      RR     RR  II    SS     SS      *
  7.    *      WW    WW    WW   BB     BB     TT      RR     RR  II    SS             *
  8.    *      WW   WWWW   WW   BBBBBBB       TT      RR   RRR   II     SSSSSSS       *
  9.    *       WW WW  WW WW    BB    BB      TT      RRRRRR     II           SS      *
  10.    *       WWWW    WWWW    BB     BB     TT      RR   RR    II           SS      *
  11.    *        WWW    WWW     BB     BB     TT      RR    RR   II    SS     SS      *
  12.    *        WW      WW     BBBBBBBB      TT      RR     RR  II     SSSSSSS       *
  13.    *                                                                             *
  14.    *                                                                             *
  15.    *          COPYRIGHT ⌐ 1993 by Dirk B÷hmer  ( medusa@uni-paderborn.de )       *
  16.    *                                                                             *
  17.    *                            & Ralf Pieper                                    *
  18.    *                                                                             *
  19.    *          All rights reserved.                                               *
  20.    *                                                                             *
  21.    *                                                                             *
  22.    *******************************************************************************
  23. */
  24.  
  25. #include "WBTRIS.h"
  26. #include "Tiles.h"
  27. #include "TilesNI.h"
  28. #include "Logo.h"
  29. #include "pause.h"
  30.  
  31. #define TEMPLATE "LEFT=LEFTEDGE/N/K,TOP=TOPEDGE/N/K,N=NAME/K,NOLOCK=NOLOCKNAME/K/S\
  32. ,NONEXT=SHOWNONEXT/K/S,NOLACE/K/S,LEVEL/N/K\
  33. ,PULLDOWNTICKS/N/K\
  34. ,R=MOVERIGHT/K,L=MOVELEFT/K,RR=ROTATERIGHT/K,RL=ROTATELEFT/K\
  35. ,D=MOVEDOWN/K,DQ=MOVEDOWNQUICK/K"
  36.  
  37. char versionstring[] = "\0$VER: " PROG_NAME VERSION " " "von " AUTHOR;
  38.  
  39. UBYTE *CYCLELabels[] = {
  40.     (UBYTE *)"Pause",
  41.     (UBYTE *)"Go on",
  42.     NULL };
  43. ;
  44.  
  45. struct obj {
  46.   BOOL objData[4][4];
  47.   int color;
  48. };
  49.  
  50. struct obj objects[8];
  51.  
  52. int field[YSIZE+1][XSIZE+2] = {
  53.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  54.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  55.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  56.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  57.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  58.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  59.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  60.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  61.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  62.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  63.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  64.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  65.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  66.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  67.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  68.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  69.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  70.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  71.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  72.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  73.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  74.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  75.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  76.                         {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
  77.                      };
  78.  
  79. short LGXOS;
  80. short LGYOS;
  81. short BOXXSIZE;
  82. short BOXYSIZE;
  83. short NEXTXOFFSET;
  84. short MAINXOFFSET;
  85. BOOL UseLace = TRUE;
  86. short boxxsize;
  87. short boxysize;
  88. int Highscore;
  89. int Score = 0;
  90. int Lines = 0;
  91. int time = DEFAULTTICKS;
  92. int oldtime = DEFAULTTICKS;
  93. int x = XSIZE/2;
  94. int y = 0;
  95. UWORD CursorUp    = CURSOR_UP;
  96. UWORD CursorDown  = CURSOR_DOWN;
  97. UWORD CursorLeft  = CURSOR_LEFT;
  98. UWORD CursorRight = CURSOR_RIGHT;
  99. UWORD NormalSpace = SPACE   ;
  100. UWORD QuickSpace  = QUICKSPACE;
  101.  
  102. /* Timer */
  103. BYTE TimerError = 0;
  104. struct MsgPort *TimerMP = NULL;
  105. struct timerequest *TimerIO = NULL;
  106. struct Message *TimerMSG = NULL;
  107.  
  108. /* Options */
  109. char Name[25];
  110. BOOL SpacePressed = FALSE;
  111. BOOL lockname = TRUE;
  112. BOOL nextteil = TRUE;
  113. int LevelOffset = 0;
  114. int pulldownticks = 0;
  115. int WBTRIS_Window_Top = MAINWINDOWTOP;
  116. int WBTRIS_Window_Left= MAINWINDOWLEFT;
  117.  
  118. struct Library    *IntuitionBase = NULL;
  119. struct Library    *KeymapBase    = NULL;
  120. struct Library    *IconBase      = NULL;
  121. struct Window     *window        = NULL;
  122. struct obj        *objptr        = NULL;
  123. struct obj        *nextptr       = NULL;
  124. struct Screen     *myscreen      = NULL;
  125. struct TextFont   *font = NULL, *font2 = NULL;
  126.  
  127. int LineCounter = 0;
  128. int Level;
  129.  
  130. struct TextAttr helvetica13 = {"helvetica.font", 13, 0, 0};
  131. struct TextAttr topaz8 = {"topaz.font", 8, 0, 0};
  132.  
  133. APTR          VisualInfo = NULL;
  134. struct Gadget *TetrisGList = NULL;
  135. struct Gadget *TetrisGadgets[9];
  136. BOOL vonoptions = TRUE;
  137.  
  138. int obj1 = 0;
  139. int obj2 = 0;
  140. int obj3 = 0;
  141. int obj4 = 0;
  142. int obj5 = 0;
  143. int obj6 = 0;
  144. int obj7 = 0;
  145.  
  146.  
  147.  
  148.  
  149. int wbmain(struct WBStartup *wbs)
  150. {
  151.    struct DiskObject *dobj = NULL;
  152.    char **toolsarray;
  153.    char *s;
  154.    char *tail;
  155.  
  156.    if ((IconBase = OpenLibrary("icon.library", 37l)) == NULL)
  157.       exit(FALSE);
  158.  
  159.    CurrentDir(wbs->sm_ArgList->wa_Lock);
  160.    if (dobj = (struct DiskObject *) GetDiskObject(wbs->sm_ArgList->wa_Name)) {
  161.       toolsarray = (char **) dobj->do_ToolTypes;
  162.  
  163.       if (s = (char *) FindToolType(toolsarray, "LEFTEDGE"))
  164.          WBTRIS_Window_Left = atoi(s);
  165.       if (s = (char *) FindToolType(toolsarray, "TOPEDGE"))
  166.          WBTRIS_Window_Top = atoi(s);
  167.       if (s = (char *) FindToolType(toolsarray, "NAME"))
  168.          strcpy(Name, s);
  169.       if (s = (char *) FindToolType(toolsarray, "LOCKNAME")) {
  170.          if ((strcmp(s, "TRUE")) == NULL)
  171.             lockname = TRUE;
  172.          else
  173.             lockname = FALSE;
  174.       }
  175.       if (s = (char *) FindToolType(toolsarray, "SHOWNEXT")) {
  176.          if ((strcmp(s, "TRUE")) == NULL)
  177.             nextteil = TRUE;
  178.          else
  179.             nextteil = FALSE;
  180.       }
  181.       if (s = (char *) FindToolType(toolsarray, "USELACE")) {
  182.          if ((strcmp(s, "TRUE")) == NULL)
  183.             UseLace = TRUE;
  184.          else
  185.             UseLace = FALSE;
  186.       }
  187.       if (s = (char *) FindToolType(toolsarray, "LEVEL"))
  188.          LevelOffset = atoi(s);
  189.       if (s = (char *) FindToolType(toolsarray, "PULLDOWNTICKS"))
  190.          pulldownticks = 20 - atoi(s);
  191.  
  192.       if (s = (char *) FindToolType(toolsarray, "MOVERIGHT"))
  193.          CursorRight = strtol(s, &tail, 0);
  194.       if (s = (char *) FindToolType(toolsarray, "MOVELEFT"))
  195.          CursorLeft  = strtol(s, &tail, 0);
  196.       if (s = (char *) FindToolType(toolsarray, "ROTATERIGHT"))
  197.          CursorUp    = strtol(s, &tail, 0);
  198.       if (s = (char *) FindToolType(toolsarray, "ROTATELEFT"))
  199.          CursorDown  = strtol(s, &tail, 0);
  200.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWN"))
  201.          NormalSpace = strtol(s, &tail, 0);
  202.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWNQUICK"))
  203.          QuickSpace  = strtol(s, &tail, 0);
  204.  
  205.       FreeDiskObject(dobj);
  206.    }
  207.  
  208.    if (IconBase)
  209.       CloseLibrary(IconBase);
  210.    Real_Main();
  211. }
  212.  
  213.  
  214.  
  215. int main(void)
  216. {
  217.    int i;
  218.    long options[14];
  219.    struct RDArgs *args;
  220.  
  221.    for (i=0; i<14; i++)
  222.       options[i] = 0L;
  223.  
  224.    args = ReadArgs(TEMPLATE, options, NULL);
  225.  
  226.    if (args) {
  227.       if (options[0])
  228.          WBTRIS_Window_Left = *(int *) options[0];
  229.       if (options[1])
  230.          WBTRIS_Window_Top = *(int *) options[1];
  231.       if (options[2])
  232.          strcpy(Name, (char *) options[2]);
  233.       if (options[3])
  234.          lockname = !options[3];
  235.       if (options[4])
  236.          nextteil = options[4];
  237.       if (options[5])
  238.          UseLace = !options[5];
  239.       if (options[6])
  240.          LevelOffset = *(int *) options[6];
  241.       if (options[7])
  242.          pulldownticks = 20 - *(int *) options[7];
  243.       if (options[8])
  244.          CursorRight = (UWORD) strtol((char *) options[8], NULL, 0);
  245.       if (options[9])
  246.          CursorLeft = (UWORD) strtol((char *) options[9], NULL, 0);
  247.       if (options[10])
  248.          CursorUp = (UWORD) strtol((char *) options[10], NULL, 0);
  249.       if (options[11])
  250.          CursorDown = (UWORD) strtol((char *) options[11], NULL, 0);
  251.       if (options[12])
  252.          NormalSpace = (UWORD) strtol((char *) options[12], NULL, 0);
  253.       if (options[13])
  254.          QuickSpace = (UWORD) strtol((char *) options[13], NULL, 0);
  255.    }
  256.    if (args)
  257.       FreeArgs(args);
  258.  
  259.    Real_Main();
  260. }
  261.  
  262.  
  263.  
  264. int Real_Main(void)
  265. {
  266.    struct IntuiMessage *imsg;
  267.    struct InputEvent    inputevent = {0};
  268.    struct RastPort     *rp;
  269.    struct DateStamp     DS;
  270.    struct Gadget       *gad;
  271.    UWORD                lc, tc;
  272.    LONG                 windowsignal, timersignal;
  273.    COUNT                i;
  274.    BOOL                 Done = FALSE;
  275.    APTR                *eventptr;
  276.    long                 mask;
  277.    struct I0ExtSer     *reply;
  278.  
  279.    InitObjects();
  280.    openall();                    /* open Fonts, Libraries, VisualInfo, etc*/
  281.  
  282.    if (UseLace) {
  283.       LGXOS = 5;
  284.       LGYOS = 0;
  285.       boxxsize = BOXXSIZE = 18;
  286.       boxysize = BOXYSIZE = 16;
  287.       NEXTXOFFSET = 14;
  288.       MAINXOFFSET = 122;
  289.    } else {
  290.       LGXOS = 15;
  291.       LGYOS = 15;
  292.       boxxsize = BOXXSIZE = 16;
  293.       boxysize = BOXYSIZE = 8;
  294.       NEXTXOFFSET = 155;
  295.       MAINXOFFSET = 252;
  296.    }
  297.  
  298. /*   OpenOptions(WBTRIS_Window_Left, WBTRIS_Window_Top); */
  299.  
  300.    gad = CreateAllGadgets(myscreen);
  301.  
  302.    window = OpenWindowTags(NULL,
  303.                             WA_Left,    WBTRIS_Window_Left,
  304.                             WA_Top,     WBTRIS_Window_Top,
  305.                             WA_Width,   XSIZE*boxxsize + 35 + MAINXOFFSET,
  306.                             WA_Height,  YSIZE*boxysize + 15 + YOFFSET,
  307.                             WA_Title,   "WBTRIS  ⌐ 1993 by Dirk B÷hmer & Ralf Pieper",
  308.                             WA_Flags,   WFLG_CLOSEGADGET | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET ,
  309.                             WA_Gadgets, TetrisGList,
  310.                             WA_IDCMP,   BUTTONIDCMP | NUMBERIDCMP | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW
  311.                                       | WFLG_DEPTHGADGET | WFLG_SMART_REFRESH  | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
  312.                             TAG_DONE);
  313.  
  314.    if (window == NULL)
  315.       closeout("Can't open window",RETURN_FAIL);
  316.  
  317.    rp = window->RPort;
  318.    x = XSIZE/2 - 1;
  319.    Level = LevelOffset;
  320.    oldtime = time = DEFAULTTICKS - Level*2;
  321.    nextptr = RandomObject();
  322.    objptr = RandomObject();
  323.    y = 0;
  324.    if (InFirstLine(objptr) == TRUE)
  325.       y = 1;
  326.    if (nextteil == TRUE)
  327.       Draw_NextObject(rp, nextptr);
  328.  
  329.    GT_RefreshWindow( window, NULL );
  330.  
  331.    DrawWindow(rp);
  332.  
  333.  
  334.    timersignal  = 1L << TimerMP->mp_SigBit;
  335.    windowsignal = 1L << window->UserPort->mp_SigBit;
  336.  
  337.    /* Initialize InputEvent structure (already cleared to 0) */
  338.    inputevent.ie_Class = IECLASS_RAWKEY;
  339.  
  340.    Highscore = Loadhiscore();
  341.  
  342.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  343.                           GTNM_Number, (ULONG)Highscore,
  344.                           TAG_END);
  345.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  346.                           GTNM_Number, (ULONG)Level, TAG_END);
  347.  
  348.    TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  349.    TimerIO->tr_time.tv_secs = 0;
  350.    TimerIO->tr_time.tv_micro = time * 20000;
  351.    SendIO((struct IORequest *) TimerIO);
  352.  
  353.    while(!Done) {
  354.       mask = Wait(timersignal | windowsignal);
  355.  
  356.       /*
  357.       ** Signal kommt vom Timer
  358.       */
  359.       if (mask & timersignal) {
  360.          while(reply = (struct I0ExtSer *)GetMsg(TimerMP))
  361.          {
  362.             /* we don't need these messages */
  363.          }
  364.          AbortIO((struct IORequest *) TimerIO);
  365.          WaitIO((struct IORequest *) TimerIO);
  366. /*         if (SpacePressed) {
  367.             TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  368.             TimerIO->tr_time.tv_secs = 0;
  369.             TimerIO->tr_time.tv_micro = pulldownticks/2 * 20000;
  370.             SendIO((struct IORequest *) TimerIO);
  371.          } else { */
  372.             TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  373.             TimerIO->tr_time.tv_secs = 0;
  374.             TimerIO->tr_time.tv_micro = time * 20000;
  375.             SendIO((struct IORequest *) TimerIO);
  376. /*         }*/
  377.          if (CollisionDown(objptr, field, x, y) == FALSE) {
  378.             AbortIO((struct IORequest *) TimerIO);
  379.             WaitIO((struct IORequest *) TimerIO);
  380.             time = oldtime;
  381.             SetNewMatrix(objptr, field, x, y);
  382.             CleanUp(rp, field);
  383.             Done = GameOver(rp,field,lockname);
  384.             if (Done == FALSE) {
  385.                objptr = nextptr;
  386.                nextptr = RandomObject();
  387.                y = 0 ;
  388.                if (InFirstLine(objptr) == TRUE)
  389.                   y = 1;
  390.  
  391.                x = XSIZE/2 - 1;
  392.                ClearNextField(rp);
  393.                if (nextteil == TRUE)
  394.                   Draw_NextObject(rp , nextptr);
  395.             }
  396.          } else {
  397.             Draw_Object(rp, x, y, objptr, FALSE);
  398.             y=y+1;
  399.             Draw_Object(rp, x, y, objptr, TRUE);
  400.          }
  401.       }
  402.  
  403.       /*
  404.       ** Signal kommt von Gadgets, Fenster, Tasten, usw.
  405.       */
  406.       if (mask & windowsignal) {
  407.          while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  408.             switch(imsg->Class) {
  409.                case IDCMP_GADGETUP:
  410.                   gad = (struct Gadget *)imsg->IAddress;
  411.                   switch(gad->GadgetID) {
  412.                      case GD_PauseGadget:
  413.                         Done = Pause(rp, window, field);
  414.                         break;
  415.  
  416.                      case GD_NewGadget:
  417.                         NewGame(rp, field, FALSE, FALSE);
  418.                         break;
  419.  
  420.                      case GD_QuitGadget:
  421.                         QuitGame();
  422.                         Done = TRUE;
  423.                         break;
  424.  
  425.                      case GD_OptGadget:
  426.                         OpenOptions(window->LeftEdge, window->TopEdge);
  427.                         NewGame(rp, field, FALSE, TRUE);
  428.                         break;
  429.                   }
  430.                   break;
  431.  
  432.                   case IDCMP_REFRESHWINDOW:
  433.                      /* This handling is REQUIRED with GadTools. */
  434.                      GT_BeginRefresh(window);
  435.                      GT_EndRefresh(window, TRUE);
  436.                      break;
  437.  
  438.                   case IDCMP_INACTIVEWINDOW:
  439.                      WaitForActivateWindow(rp);
  440.                      break;
  441.  
  442.                   case IDCMP_CLOSEWINDOW:
  443.                      QuitGame();
  444.                      Done = TRUE;
  445.                      break;
  446.  
  447.                   case IDCMP_RAWKEY:
  448.                      inputevent.ie_Code = imsg->Code;
  449.                      inputevent.ie_Qualifier = imsg->Qualifier;
  450.  
  451.                      if (imsg->Code == CursorUp) {
  452.                         if (Rotate_Matrixl(objptr, field, x, y)) {
  453.                            Rotate_Matrixr(objptr, field, x, y);
  454.                            Draw_Object(rp, x, y, objptr, FALSE);
  455.                            Rotate_Matrixl(objptr, field, x, y);
  456.                            Draw_Object(rp, x, y, objptr, TRUE);
  457.                         }
  458.                      } else {
  459.                      if (imsg->Code == CursorDown) {
  460.                         if (Rotate_Matrixr(objptr, field, x, y)) {
  461.                            Rotate_Matrixl(objptr, field, x, y);
  462.                            Draw_Object(rp, x, y, objptr, FALSE);
  463.                            Rotate_Matrixr(objptr, field, x, y);
  464.                            Draw_Object(rp, x, y, objptr, TRUE);
  465.                         }
  466.                      } else {
  467.                      if (imsg->Code == CursorLeft) {
  468.                         if (CollisionLeft(objptr, field, x, y) == TRUE) {
  469.                            Draw_Object(rp, x, y, objptr, FALSE);
  470.                            x = x-1;
  471.                            Draw_Object(rp, x, y, objptr, TRUE);
  472.                         }
  473.                      } else {
  474.                      if (imsg->Code == CursorRight) {
  475.                         if (CollisionRight(objptr, field, x, y) == TRUE) {
  476.                            Draw_Object(rp, x, y, objptr, FALSE);
  477.                            x=x+1;
  478.                            Draw_Object(rp, x, y, objptr, TRUE);
  479.                         }
  480.                      } else {
  481.                      if (imsg->Code == NormalSpace) {
  482.                         if (!SpacePressed) {
  483.                            AbortIO((struct IORequest *) TimerIO);
  484.                            WaitIO((struct IORequest *) TimerIO);
  485.                            SpacePressed = TRUE;
  486.                            oldtime = time;
  487.                            time = pulldownticks;
  488.                         }
  489.                      } else {
  490.                      if (imsg->Code == QuickSpace) {
  491.                         AbortIO((struct IORequest *) TimerIO);
  492.                         WaitIO((struct IORequest *) TimerIO);
  493.                         oldtime = time;
  494.                         time = 0;
  495.                      } else {
  496.                         if (SpacePressed) {
  497.                           SpacePressed = FALSE;
  498.                            time = oldtime;
  499.                         }
  500.                      }}}}}}
  501.                      break;
  502.                   default:
  503.             }
  504.             ReplyMsg((struct Message *)imsg);
  505.          }
  506.       }
  507.    }
  508.  
  509.    closeall();
  510.    exit(RETURN_OK);
  511. }
  512.  
  513.  
  514.  
  515. /*
  516. ** Fragt die Kollision nach rechts ab
  517. ** FALSE, wenn Object oder rechte Wand im Weg
  518. ** TRUE , wenn Object nach rechts verschoben werden kann
  519. */
  520. BOOL CollisionRight(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  521. {
  522.    short i,j;
  523.  
  524.    for (j=3; j>=0; j--)
  525.       for (i=0; i<4; i++) {
  526.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x+1] != 0))
  527.             return(FALSE);
  528.       }
  529.    return(TRUE);
  530. }
  531.  
  532.  
  533.  
  534. /*
  535. ** Fragt die Kollision nach links ab
  536. ** FALSE, wenn Object oder linke Wand im Weg
  537. ** TRUE , wenn Object nach links verschoben werden kann
  538. */
  539. BOOL CollisionLeft(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  540. {
  541.    short i,j;
  542.  
  543.    for (j=0; j<4; j++)
  544.       for (i=0; i<4; i++) {
  545.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x-1] != 0))
  546.             return(FALSE);
  547.       }
  548.    return(TRUE);
  549. }
  550.  
  551.  
  552.  
  553. /*
  554. ** Fragt die Kollision nach unten ab
  555. ** FALSE, wenn Object oder Boden im Weg
  556. ** TRUE , wenn Object nach unten verschoben werden kann
  557. */
  558. BOOL CollisionDown(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  559. {
  560.    short i,j;
  561.  
  562.    for (j=0; j<4; j++)
  563.       for (i=0; i<4; i++) {
  564.          if ((objptr->objData[i][j] > 0) && (field[y+i][j+x] != 0)) {
  565.             Score = Score + 1;
  566.             return(FALSE);
  567.          }
  568.       }
  569.    return(TRUE);
  570. }
  571.  
  572.  
  573.  
  574. void openall(void)
  575. {
  576.    if ((TimerMP = CreatePort(NULL, NULL)) == NULL)
  577.       closeout("Couldn't create messageport", RETURN_FAIL);
  578.  
  579.    if ((TimerIO = (struct timerequest *) CreateExtIO(TimerMP, sizeof(struct timerequest))) == NULL)
  580.       closeout("Couldn't create IOrequest", RETURN_FAIL);
  581.  
  582.    if ((TimerError = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO, 0L)) != NULL)
  583.       closeout("Couldn't open timer.device", RETURN_FAIL);
  584.  
  585.    if ((KeymapBase = OpenLibrary("keymap.library", 37)) == NULL)
  586.       closeout("Kickstart 2.0 required",RETURN_FAIL);
  587.  
  588.    if ((IntuitionBase = OpenLibrary("intuition.library", 37)) == NULL)
  589.       closeout("Can't open intuition",RETURN_FAIL);
  590.  
  591.    if ((font = OpenDiskFont(&helvetica13)) == NULL)
  592.       closeout("Failed to open Helvetica 13", RETURN_FAIL);
  593.  
  594.    if ((font2 = OpenDiskFont(&topaz8)) == NULL)
  595.       closeout("Failed to open Topaz 8", RETURN_FAIL);
  596.  
  597.    if ((myscreen = LockPubScreen(NULL)) == NULL)
  598.       closeout("Couldn't lock default public screen", RETURN_FAIL);
  599.  
  600.    if ((myscreen->Height) < 450)
  601.       UseLace = FALSE;
  602.  
  603.    if ((VisualInfo = GetVisualInfo(myscreen, TAG_END)) == NULL)
  604.       closeout("GetVisualInfo() failed", RETURN_FAIL);
  605. }
  606.  
  607.  
  608.  
  609. void closeall(void)
  610. {
  611.    AbortIO((struct IORequest *) TimerIO);
  612.    WaitIO((struct IORequest *) TimerIO);
  613.  
  614.    if (window)
  615.       CloseWindow(window);
  616.  
  617.    if (TetrisGList)
  618.       FreeGadgets(TetrisGList);
  619.  
  620.    if (VisualInfo)
  621.       FreeVisualInfo(VisualInfo);
  622.  
  623.    if (myscreen)
  624.       UnlockPubScreen(NULL, myscreen);
  625.  
  626.    if (IntuitionBase)
  627.       CloseLibrary(IntuitionBase);
  628.  
  629.    if (KeymapBase)
  630.       CloseLibrary(KeymapBase);
  631.  
  632.    if (!TimerError)
  633.       CloseDevice((struct IORequest *) TimerIO);
  634.  
  635.    if (TimerIO)
  636.       DeleteExtIO((struct IORequest *) TimerIO);
  637.  
  638.    if (TimerMP)
  639.       DeletePort(TimerMP);
  640.  
  641.    exit(0);
  642. }
  643.  
  644.  
  645.  
  646. void closeout(UBYTE *errstring, LONG rc)
  647. {
  648.    struct EasyStruct myES = {
  649.       sizeof(struct EasyStruct),
  650.       0,
  651.       "WBTRIS Error",
  652.       "Error: %s\n",
  653.       "OK",
  654.    };
  655.  
  656.    if (*errstring)
  657.       EasyRequest(NULL, &myES, NULL, errstring);
  658.  
  659.     closeall();
  660.     exit(rc);
  661. }
  662.  
  663.  
  664.  
  665. BOOL Rotate_Matrixr(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  666. {
  667.    short i, j;
  668.    struct obj b[1];
  669.  
  670.    b[0].objData[3][0] = objptr->objData[0][0];
  671.    b[0].objData[2][0] = objptr->objData[0][1];
  672.    b[0].objData[1][0] = objptr->objData[0][2];
  673.    b[0].objData[0][0] = objptr->objData[0][3];
  674.    b[0].objData[3][1] = objptr->objData[1][0];
  675.    b[0].objData[2][1] = objptr->objData[1][1];
  676.    b[0].objData[1][1] = objptr->objData[1][2];
  677.    b[0].objData[0][1] = objptr->objData[1][3];
  678.    b[0].objData[3][2] = objptr->objData[2][0];
  679.    b[0].objData[2][2] = objptr->objData[2][1];
  680.    b[0].objData[1][2] = objptr->objData[2][2];
  681.    b[0].objData[0][2] = objptr->objData[2][3];
  682.    b[0].objData[3][3] = objptr->objData[3][0];
  683.    b[0].objData[2][3] = objptr->objData[3][1];
  684.    b[0].objData[1][3] = objptr->objData[3][2];
  685.    b[0].objData[0][3] = objptr->objData[3][3];
  686.  
  687.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1) == TRUE)) {
  688.       for (i=0; i<4; i++)
  689.          for (j=0; j<4; j++)
  690.             objptr->objData[i][j] = b[0].objData[i][j];
  691.       return(TRUE);
  692.    }
  693.    return(FALSE);
  694. }
  695.  
  696.  
  697.  
  698. BOOL Rotate_Matrixl(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  699. {
  700.    short i, j;
  701.    struct obj b[1];
  702.  
  703.    b[0].objData[0][3] = objptr->objData[0][0];
  704.    b[0].objData[1][3] = objptr->objData[0][1];
  705.    b[0].objData[2][3] = objptr->objData[0][2];
  706.    b[0].objData[3][3] = objptr->objData[0][3];
  707.    b[0].objData[0][2] = objptr->objData[1][0];
  708.    b[0].objData[1][2] = objptr->objData[1][1];
  709.    b[0].objData[2][2] = objptr->objData[1][2];
  710.    b[0].objData[3][2] = objptr->objData[1][3];
  711.    b[0].objData[0][1] = objptr->objData[2][0];
  712.    b[0].objData[1][1] = objptr->objData[2][1];
  713.    b[0].objData[2][1] = objptr->objData[2][2];
  714.    b[0].objData[3][1] = objptr->objData[2][3];
  715.    b[0].objData[0][0] = objptr->objData[3][0];
  716.    b[0].objData[1][0] = objptr->objData[3][1];
  717.    b[0].objData[2][0] = objptr->objData[3][2];
  718.    b[0].objData[3][0] = objptr->objData[3][3];
  719.  
  720.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1) == TRUE)) {
  721.       for (i=0; i<4; i++)
  722.          for (j=0; j<4; j++)
  723.             objptr->objData[i][j] = b[0].objData[i][j];
  724.       return(TRUE);
  725.    }
  726.    return(FALSE);
  727. }
  728.  
  729.  
  730.  
  731. void Draw_NextObject(struct RastPort *rp, struct obj *objptr)
  732. {
  733.    short i,j;
  734.    for (i=0; i<4; i++) {
  735.       for (j=0; j<4; j++)
  736.          if (objptr->objData[i][j] > 0)
  737.             Draw_Box(rp, j-5, i, objptr->color, TRUE);
  738.    }
  739. }
  740.  
  741.  
  742.  
  743. void ClearNextField(struct RastPort *rp)
  744. {
  745.    short i,j;
  746.    for (i=0; i<4; i++) {
  747.       for (j=0; j<4; j++)
  748.             Draw_Box(rp, j-5, i, 0, FALSE);
  749.    }
  750. }
  751.  
  752.  
  753.  
  754. void Draw_Object(struct RastPort *rp, int x, int y, struct obj *objptr, BOOL malen)
  755. {
  756.    short i,j;
  757.    for (i=0; i<4; i++) {
  758.       for (j=0; j<4; j++)
  759.          if (objptr->objData[i][j] > 0)
  760.             Draw_Box(rp, x+j, y+i-1, objptr->color, malen);
  761.    }
  762. }
  763.  
  764.  
  765.  
  766. void Draw_Box(struct RastPort *rp, int x, int y, int color, int malen)
  767. {
  768.    if (UseLace) {
  769.       if (malen == TRUE) {
  770.          switch(color) {
  771.             case 1:
  772.                DrawImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  773.                break;
  774.             case 2:
  775.                DrawImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  776.                break;
  777.             case 3:
  778.                DrawImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  779.                break;
  780.             case 4:
  781.                DrawImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  782.                break;
  783.             case 5:
  784.                DrawImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  785.                break;
  786.             case 6:
  787.                DrawImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  788.                break;
  789.             case 7:
  790.                DrawImage(rp, &Gruen, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  791.                break;
  792.          }
  793.       } else {
  794.          switch(color) {
  795.             case 0:
  796.                SetAPen(rp, 0);
  797.                RectFill(rp, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE, YOFFSET + y*boxysize + BOXYSIZE);
  798.                break;
  799.             case 1:
  800.                EraseImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  801.                break;
  802.             case 2:
  803.                EraseImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  804.                break;
  805.             case 3:
  806.                EraseImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  807.                break;
  808.             case 4:
  809.                EraseImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  810.                break;
  811.             case 5:
  812.                EraseImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  813.                break;
  814.             case 6:
  815.                EraseImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  816.                break;
  817.             case 7:
  818.                EraseImage(rp, &Gruen, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  819.                break;
  820.          }
  821.       }
  822.    } else {
  823.       if (malen == TRUE) {
  824.          switch(color) {
  825.             case 1:
  826.                DrawImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  827.                break;
  828.             case 2:
  829.                DrawImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  830.                break;
  831.             case 3:
  832.                DrawImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  833.                break;
  834.             case 4:
  835.                DrawImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  836.                break;
  837.             case 5:
  838.                DrawImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  839.                break;
  840.             case 6:
  841.                DrawImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  842.                break;
  843.             case 7:
  844.                DrawImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  845.                break;
  846.          }
  847.       } else {
  848.          switch(color) {
  849.             case 0:
  850.                SetAPen(rp, 0);
  851.                RectFill(rp, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE, YOFFSET + y*boxysize + BOXYSIZE);
  852.                break;
  853.             case 1:
  854.                EraseImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  855.                break;
  856.             case 2:
  857.                EraseImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  858.                break;
  859.             case 3:
  860.                EraseImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  861.                break;
  862.             case 4:
  863.                EraseImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  864.                break;
  865.             case 5:
  866.                EraseImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  867.                break;
  868.             case 6:
  869.                EraseImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  870.                break;
  871.             case 7:
  872.                EraseImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize, YOFFSET + y*boxysize);
  873.                break;
  874.          }
  875.       }
  876.    }
  877. }
  878.  
  879.  
  880.  
  881. struct obj *RandomObject(void)
  882. {
  883.    static ULONG RandomResult = 0L; /* So the last random-number is still stored ! */
  884.    ULONG Sec,Mic;
  885.  
  886.    CurrentTime((LONG *)&Sec,(LONG *)&Mic);
  887.  
  888.    RandomResult *= Sec;
  889.    RandomResult += Mic;
  890.  
  891.    while (RandomResult > 32767L) RandomResult = RandomResult>>1;
  892.  
  893.    RandomResult = RandomResult % 7;
  894.  
  895.    UpdateStatistic(RandomResult);
  896.  
  897.    switch(RandomResult) {
  898.       case 0:
  899.          return(&objects[1]);
  900.          break;
  901.       case 1:
  902.          return(&objects[2]);
  903.          break;
  904.       case 2:
  905.          return(&objects[3]);
  906.          break;
  907.       case 3:
  908.          return(&objects[4]);
  909.          break;
  910.       case 4:
  911.          return(&objects[5]);
  912.          break;
  913.       case 5:
  914.          return(&objects[6]);
  915.          break;
  916.       default:
  917.          return(&objects[7]);
  918.    }
  919. }
  920.  
  921.  
  922.  
  923. void DrawWindow(struct RastPort *rp)
  924. {
  925.    /* Mainfield */
  926.    if (UseLace)
  927.       DrawBevelBox(rp, MAINXOFFSET+14, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  928.    else
  929.       DrawBevelBox(rp, MAINXOFFSET+13, YOFFSET-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  930.  
  931.    /* Next Object Field */
  932.    DrawBevelBox(rp, NEXTXOFFSET+14, YOFFSET-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  933.  
  934.    /* Logo */
  935.    if (UseLace)
  936.       DrawImage(rp, &logo, LGXOS + 20, LGYOS + 320);
  937.    else
  938.       DrawImage(rp, &logo, LGXOS, LGYOS + 3);
  939. }
  940.  
  941.  
  942.  
  943. void SetNewMatrix(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  944. {
  945.    short line, column;
  946.  
  947.    for (line=0; line<4; line++)
  948.       for (column=0; column<4; column++) {
  949.          if (objptr->objData[line][column] == 1)
  950.             field[y+line-1][x+column] = objptr->color;
  951.       }
  952. }
  953.  
  954.  
  955.  
  956. void CleanUp(struct RastPort *rp, int field[YSIZE+1][XSIZE+2])
  957. {
  958.    int i, j, line, column;
  959.    BOOL Update = FALSE;
  960.    BOOL KeineNull = TRUE;
  961.  
  962.    Lines = 0;
  963.    for (line=1; line < YSIZE; line++) {
  964.       for (column=1; column < XSIZE+1; column++)
  965.          if (field[line][column] == 0)
  966.             KeineNull = FALSE;
  967.  
  968.       if (KeineNull == TRUE)
  969.       {
  970.          Lines++;
  971.          Update = TRUE;
  972.          for (j=line; j>0; j--)
  973.             for (i=1; i<XSIZE+1; i++)
  974.                field[j][i] = field[j-1][i];
  975.       }
  976.       KeineNull = TRUE;
  977.    }
  978.    if (Update == TRUE) {
  979.       for (line=1; line < YSIZE; line++) {
  980.          for (column=1; column < XSIZE+1; column++)
  981.             switch(field[line][column]) {
  982.                case 0:
  983.                   Draw_Box(rp, column, line, 0, FALSE);
  984.                   break;
  985.                case 1:
  986.                   Draw_Box(rp, column, line, 1, TRUE);
  987.                   break;
  988.                case 2:
  989.                   Draw_Box(rp, column, line, 2, TRUE);
  990.                   break;
  991.                case 3:
  992.                   Draw_Box(rp, column, line, 3, TRUE);
  993.                   break;
  994.                case 4:
  995.                   Draw_Box(rp, column, line, 4, TRUE);
  996.                   break;
  997.                case 5:
  998.                   Draw_Box(rp, column, line, 5, TRUE);
  999.                   break;
  1000.                case 6:
  1001.                   Draw_Box(rp, column, line, 6, TRUE);
  1002.                   break;
  1003.                case 7:
  1004.                   Draw_Box(rp, column, line, 7, TRUE);
  1005.                   break;
  1006.             }
  1007.                                                                                                    }
  1008.    }
  1009.  
  1010.    LineCounter = LineCounter + Lines;
  1011.    Level = LineCounter / 10 + LevelOffset;
  1012.    if (Level >= 20)
  1013.       oldtime = 0;
  1014.    else
  1015.       oldtime = DEFAULTTICKS - Level*2;
  1016.    time = oldtime;
  1017.    Score = Score + 10*Lines*Lines;
  1018.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1019.                      GTNM_Number, (ULONG)Score,
  1020.                      TAG_END);
  1021.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1022.                      GTNM_Number, (ULONG)Level,
  1023.                      TAG_END);
  1024.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1025.                      GTNM_Number, (ULONG)LineCounter,
  1026.                      TAG_END);
  1027. }
  1028.  
  1029.  
  1030.  
  1031. /*
  1032. ** Ist der obere Rand erreicht, dann ist das Spiel zu Ende
  1033. ** TRUE,  wenn oberer Rand erreicht
  1034. ** FALSE, wenn nicht
  1035. */
  1036. BOOL GameOver(struct RastPort *rp, int field[YSIZE+1][XSIZE+2],BOOL lockname)
  1037. {
  1038.    int column;
  1039.  
  1040.    for (column=0; column<=XSIZE; column++) {
  1041.       if (field[1][column] > 0) {
  1042.          if (Score > Highscore)
  1043.          Highscore = Score;
  1044.  
  1045.          Enterhighscore(window, Score, LineCounter);
  1046.  
  1047.          if ((AskContinue()) == TRUE) {
  1048.              Score = 0;
  1049.              LineCounter = 0;
  1050.              Level = LevelOffset;
  1051.              if (lockname == TRUE) {
  1052.                 NewGame(rp, field, TRUE, FALSE);
  1053.              } else {
  1054.                 OpenOptions(window->LeftEdge, window->TopEdge);
  1055.                 NewGame(rp, field, TRUE, TRUE);
  1056.              }
  1057.          }
  1058.          else {
  1059.             return(TRUE);
  1060.          }
  1061.       }
  1062.    }
  1063.    return(FALSE);
  1064. }
  1065.  
  1066.  
  1067.  
  1068. /*
  1069. ** Hier wird den Objekten die Form und die Farbe gegeben
  1070. */
  1071. void InitObjects(void)
  1072. {
  1073.   objects[0].objData[0][0] = 0; objects[0].objData[0][1] = 0; objects[0].objData[0][2] = 0; objects[0].objData[0][3] = 0;
  1074.   objects[0].objData[1][0] = 0; objects[0].objData[1][1] = 0; objects[0].objData[1][2] = 0; objects[0].objData[1][3] = 0;
  1075.   objects[0].objData[2][0] = 0; objects[0].objData[2][1] = 0; objects[0].objData[2][2] = 0; objects[0].objData[2][3] = 0;
  1076.   objects[0].objData[3][0] = 0; objects[0].objData[3][1] = 0; objects[0].objData[3][2] = 0; objects[0].objData[3][3] = 0;
  1077.   objects[0].color = 0;
  1078.  
  1079.   objects[1].objData[0][0] = 0; objects[1].objData[0][1] = 0; objects[1].objData[0][2] = 0; objects[1].objData[0][3] = 0;
  1080.   objects[1].objData[1][0] = 0; objects[1].objData[1][1] = 1; objects[1].objData[1][2] = 1; objects[1].objData[1][3] = 0;
  1081.   objects[1].objData[2][0] = 0; objects[1].objData[2][1] = 1; objects[1].objData[2][2] = 1; objects[1].objData[2][3] = 0;
  1082.   objects[1].objData[3][0] = 0; objects[1].objData[3][1] = 0; objects[1].objData[3][2] = 0; objects[1].objData[3][3] = 0;
  1083.   objects[1].color = 1;
  1084.  
  1085.   objects[2].objData[0][0] = 0; objects[2].objData[0][1] = 1; objects[2].objData[0][2] = 0; objects[2].objData[0][3] = 0;
  1086.   objects[2].objData[1][0] = 0; objects[2].objData[1][1] = 1; objects[2].objData[1][2] = 0; objects[2].objData[1][3] = 0;
  1087.   objects[2].objData[2][0] = 0; objects[2].objData[2][1] = 1; objects[2].objData[2][2] = 0; objects[2].objData[2][3] = 0;
  1088.   objects[2].objData[3][0] = 0; objects[2].objData[3][1] = 1; objects[2].objData[3][2] = 0; objects[2].objData[3][3] = 0;
  1089.   objects[2].color = 2;
  1090.  
  1091.   objects[3].objData[0][0] = 0; objects[3].objData[0][1] = 0; objects[3].objData[0][2] = 0; objects[3].objData[0][3] = 0;
  1092.   objects[3].objData[1][0] = 0; objects[3].objData[1][1] = 0; objects[3].objData[1][2] = 1; objects[3].objData[1][3] = 0;
  1093.   objects[3].objData[2][0] = 0; objects[3].objData[2][1] = 1; objects[3].objData[2][2] = 1; objects[3].objData[2][3] = 0;
  1094.   objects[3].objData[3][0] = 0; objects[3].objData[3][1] = 0; objects[3].objData[3][2] = 1; objects[3].objData[3][3] = 0;
  1095.   objects[3].color = 3;
  1096.  
  1097.   objects[4].objData[0][0] = 0; objects[4].objData[0][1] = 0; objects[4].objData[0][2] = 0; objects[4].objData[0][3] = 0;
  1098.   objects[4].objData[1][0] = 1; objects[4].objData[1][1] = 1; objects[4].objData[1][2] = 1; objects[4].objData[1][3] = 0;
  1099.   objects[4].objData[2][0] = 0; objects[4].objData[2][1] = 0; objects[4].objData[2][2] = 1; objects[4].objData[2][3] = 0;
  1100.   objects[4].objData[3][0] = 0; objects[4].objData[3][1] = 0; objects[4].objData[3][2] = 0; objects[4].objData[3][3] = 0;
  1101.   objects[4].color = 4;
  1102.  
  1103.   objects[5].objData[0][0] = 0; objects[5].objData[0][1] = 0; objects[5].objData[0][2] = 0; objects[5].objData[0][3] = 0;
  1104.   objects[5].objData[1][0] = 0; objects[5].objData[1][1] = 0; objects[5].objData[1][2] = 1; objects[5].objData[1][3] = 0;
  1105.   objects[5].objData[2][0] = 1; objects[5].objData[2][1] = 1; objects[5].objData[2][2] = 1; objects[5].objData[2][3] = 0;
  1106.   objects[5].objData[3][0] = 0; objects[5].objData[3][1] = 0; objects[5].objData[3][2] = 0; objects[5].objData[3][3] = 0;
  1107.   objects[5].color = 5;
  1108.  
  1109.   objects[6].objData[0][0] = 0; objects[6].objData[0][1] = 1; objects[6].objData[0][2] = 0; objects[6].objData[0][3] = 0;
  1110.   objects[6].objData[1][0] = 0; objects[6].objData[1][1] = 1; objects[6].objData[1][2] = 1; objects[6].objData[1][3] = 0;
  1111.   objects[6].objData[2][0] = 0; objects[6].objData[2][1] = 0; objects[6].objData[2][2] = 1; objects[6].objData[2][3] = 0;
  1112.   objects[6].objData[3][0] = 0; objects[6].objData[3][1] = 0; objects[6].objData[3][2] = 0; objects[6].objData[3][3] = 0;
  1113.   objects[6].color = 6;
  1114.  
  1115.   objects[7].objData[0][0] = 0; objects[7].objData[0][1] = 0; objects[7].objData[0][2] = 0; objects[7].objData[0][3] = 0;
  1116.   objects[7].objData[1][0] = 0; objects[7].objData[1][1] = 0; objects[7].objData[1][2] = 1; objects[7].objData[1][3] = 0;
  1117.   objects[7].objData[2][0] = 0; objects[7].objData[2][1] = 1; objects[7].objData[2][2] = 1; objects[7].objData[2][3] = 0;
  1118.   objects[7].objData[3][0] = 0; objects[7].objData[3][1] = 1; objects[7].objData[3][2] = 0; objects[7].objData[3][3] = 0;
  1119.   objects[7].color = 7;
  1120. }
  1121.  
  1122.  
  1123. /*
  1124. ** Das Programm kann angehalten werden
  1125. */
  1126. BOOL Pause(struct RastPort *rp, struct Window *window,  int field[YSIZE+1][XSIZE+2])
  1127. {
  1128.    BOOL                 Done = FALSE;
  1129.    LONG                 windowsignal;
  1130.    struct IntuiMessage *imsg;
  1131.    struct Gadget       *gad;
  1132.    int                  line,column;
  1133.  
  1134.    GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1135.                      GTCY_Labels, &CYCLELabels[1], TAG_END);
  1136.    GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1137.                      GA_Disabled, TRUE, TAG_END);
  1138.    GT_SetGadgetAttrs(TetrisGadgets[GD_QuitGadget], window, NULL,
  1139.                      GA_Disabled, FALSE, TAG_END);
  1140.    GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1141.                      GA_Disabled, TRUE, TAG_END);
  1142.    GT_SetGadgetAttrs(TetrisGadgets[GD_StatGadget], window, NULL,
  1143.                      GA_Disabled, FALSE, TAG_END);
  1144.  
  1145.    SetAPen(rp, 0);
  1146.    RectFill(rp, MAINXOFFSET+16, YOFFSET-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15, YOFFSET + YSIZE*boxysize+1);
  1147.  
  1148.    if (UseLace)
  1149.       DrawImage(rp, &Pausebrush, 190, 150);
  1150.    else
  1151.       DrawImage(rp, &Pausebrush, 310, 85);
  1152.  
  1153.    while(!Done)
  1154.    {
  1155.       Wait(1L << window->UserPort->mp_SigBit);
  1156.  
  1157.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1158.          switch(imsg->Class) {
  1159.             case IDCMP_GADGETUP:
  1160.                gad = (struct Gadget *)imsg->IAddress;
  1161.                switch(gad->GadgetID) {
  1162.                   case GD_PauseGadget:
  1163.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1164.                                        GA_Disabled, FALSE, TAG_END);
  1165.                      GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1166.                                        GA_Disabled, FALSE, TAG_END);
  1167.                      GT_SetGadgetAttrs(TetrisGadgets[GD_QuitGadget], window, NULL,
  1168.                                        GA_Disabled, FALSE, TAG_END);
  1169.                      GT_SetGadgetAttrs(TetrisGadgets[GD_StatGadget], window, NULL,
  1170.                                        GA_Disabled, TRUE, TAG_END);
  1171.                      GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1172.                                        GA_Disabled, FALSE, TAG_END);
  1173.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1174.                                        GTCY_Labels, &CYCLELabels[0], TAG_END);
  1175.                      Done = TRUE;
  1176.                      break;
  1177.                   case GD_StatGadget:
  1178.                      statistic(window->LeftEdge, window->TopEdge, obj1, obj2, obj3, obj4, obj5, obj6, obj7);
  1179.                      break;
  1180.                }
  1181.                if (gad->GadgetID == GD_QuitGadget) {
  1182.                   QuitGame();
  1183.                   closeall();
  1184.                   exit(0);
  1185.                }
  1186.                break;
  1187.  
  1188.             case IDCMP_REFRESHWINDOW:
  1189.                GT_BeginRefresh(window);
  1190.                GT_EndRefresh(window, TRUE);
  1191.                break;
  1192.  
  1193.             case IDCMP_CLOSEWINDOW:
  1194.                QuitGame();
  1195.                closeall();
  1196.                exit(0);
  1197.                break;
  1198.          }
  1199.       }
  1200.    }
  1201.    if (UseLace)
  1202.       EraseImage(rp, &Pausebrush, 190,150);
  1203.    else
  1204.       EraseImage(rp, &Pausebrush, 310,85);
  1205.  
  1206.    for (line=1; line < YSIZE; line++) {
  1207.          for (column=1; column < XSIZE+1; column++)
  1208.             switch(field[line][column]) {
  1209.                case 0:
  1210.                   Draw_Box(rp, column, line, 0, FALSE);
  1211.                   break;
  1212.                case 1:
  1213.                   Draw_Box(rp, column, line, 1, TRUE);
  1214.                   break;
  1215.                case 2:
  1216.                   Draw_Box(rp, column, line, 2, TRUE);
  1217.                   break;
  1218.                case 3:
  1219.                   Draw_Box(rp, column, line, 3, TRUE);
  1220.                   break;
  1221.                case 4:
  1222.                   Draw_Box(rp, column, line, 4, TRUE);
  1223.                   break;
  1224.                case 5:
  1225.                   Draw_Box(rp, column, line, 5, TRUE);
  1226.                   break;
  1227.                case 6:
  1228.                   Draw_Box(rp, column, line, 6, TRUE);
  1229.                   break;
  1230.                case 7:
  1231.                   Draw_Box(rp, column, line, 7, TRUE);
  1232.                   break;
  1233.             }
  1234.    }
  1235.    return(FALSE);
  1236. }
  1237.  
  1238.  
  1239.  
  1240. /*
  1241. ** Ein neues Spiel starten
  1242. */
  1243. void NewGame(struct RastPort *rp, int field[YSIZE+1][XSIZE+2],BOOL vongameover, BOOL vonoptions)
  1244. {
  1245.    int line, column;
  1246.  
  1247. /*   obj1 = obj2 = obj3 = obj4 = obj5 = obj6 = obj7 = 0;*/
  1248.    /* Feld loeschen */
  1249.    for (line=0; line < YSIZE; line++)
  1250.       for (column=1; column<=XSIZE; column++) {
  1251.          field[line][column] = 0;
  1252.          Draw_Box(rp, column, line, 0, FALSE);
  1253.       }
  1254.  
  1255.    ClearNextField(rp);
  1256.  
  1257.    nextptr = RandomObject();
  1258.    objptr = RandomObject();
  1259.    if (nextteil == TRUE)
  1260.       Draw_NextObject(rp, nextptr);
  1261.  
  1262.    x = XSIZE/2-1;
  1263.    y = 0;
  1264.    if (InFirstLine(objptr) == TRUE)
  1265.       y = 1;
  1266.  
  1267.    if (Score > Highscore)
  1268.       Highscore = Score;
  1269.  
  1270.    if ((vongameover == FALSE) && (vonoptions == FALSE))
  1271.       Enterhighscore(window, Score, LineCounter);
  1272.  
  1273.    if (lockname == FALSE)
  1274.       if (vonoptions == FALSE)
  1275.           OpenOptions(window->LeftEdge, window->TopEdge);
  1276.  
  1277.    vongameover = FALSE;
  1278.    vonoptions = FALSE;
  1279.  
  1280.    Score = 0;
  1281.    LineCounter = 0;
  1282.    Level = LevelOffset;
  1283.    time = oldtime = DEFAULTTICKS - 2*LevelOffset;
  1284.  
  1285.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  1286.                      GTNM_Number, (ULONG)Highscore, TAG_END);
  1287.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1288.                      GTNM_Number, (ULONG)Score, TAG_END);
  1289.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1290.                      GTNM_Number, (ULONG)Level, TAG_END);
  1291.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1292.                      GTNM_Number, (ULONG)LineCounter, TAG_END);
  1293. }
  1294.  
  1295.  
  1296.  
  1297. void QuitGame(void)
  1298. {
  1299.    if (Score > Highscore) {
  1300.       Highscore = Score;
  1301.       Enterhighscore(window, Score, LineCounter);
  1302.    }
  1303. }
  1304.  
  1305.  
  1306.  
  1307. void Enterhighscore(struct Window *window, int Score, int Rows)
  1308. {
  1309.    WORD xpos, ypos;
  1310.  
  1311.    xpos = window->LeftEdge;
  1312.    ypos = window->TopEdge + 70;
  1313.  
  1314.    HiscoreList(Name, Score, Rows, xpos, ypos);
  1315. }
  1316.  
  1317.  
  1318.  
  1319. BOOL InFirstLine(struct obj *objptr)
  1320. {
  1321.    int column;
  1322.  
  1323.    for (column=0; column<4; column++)
  1324.       if (objptr->objData[0][column] == 1)
  1325.          return(TRUE);
  1326.    return(FALSE);
  1327. }
  1328.  
  1329.  
  1330.  
  1331. int Loadhiscore(void)
  1332. {
  1333.    char score[10];
  1334.    int zaehler = 0, hiscore = 0, c;
  1335.    FILE *fp;
  1336.    char *ptr;
  1337.    char FName[80];
  1338.  
  1339.    if (getenv("WBTRIS"))
  1340.       strcpy(FName, getenv("WBTRIS"));
  1341.    else
  1342.       strcpy(FName, FILENAME);
  1343.  
  1344.    ptr = &score[0];
  1345.  
  1346.    if ((fp = fopen(FName, "r")) == NULL)
  1347.       return(0);
  1348.    else {
  1349.       while (((c=getc(fp)) != EOF) && (zaehler != 2))
  1350.          if (c == '/') zaehler++;
  1351.  
  1352.       if (c != EOF) {
  1353.          while (c != '/') {
  1354.             *ptr = c;
  1355.             ptr++;
  1356.             c = getc(fp);
  1357.          }
  1358.          *ptr = '\0';
  1359.          hiscore = atoi(score);
  1360.       }
  1361.  
  1362.       fclose(fp);
  1363.       return(hiscore);
  1364.    }
  1365. }
  1366.  
  1367.  
  1368.  
  1369. BOOL AskContinue(void)
  1370. {
  1371.    struct EasyStruct myES = {
  1372.        sizeof(struct EasyStruct),
  1373.        0,
  1374.        "Continue",
  1375.        "Game over\n\nDo you want to play again ?",
  1376.        "YEA|No thanks",
  1377.        };
  1378.    LONG answer;
  1379.  
  1380. answer = EasyRequest(NULL, &myES, NULL, "(Variable)");
  1381.   switch (answer) {
  1382.       case 1:
  1383.            return(TRUE);
  1384.            break;
  1385.       case 2:
  1386.            return(FALSE);
  1387.            break;
  1388.   }
  1389. }
  1390.  
  1391.  
  1392.  
  1393. void WaitForActivateWindow(struct RastPort *rp)
  1394. {
  1395.    BOOL                 Done = FALSE;
  1396.    struct IntuiMessage *imsg;
  1397.    int line, column;
  1398.  
  1399.    SetAPen(rp, 0);
  1400.    RectFill(rp, MAINXOFFSET+16, YOFFSET-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15, YOFFSET + YSIZE*boxysize+1);
  1401.  
  1402.    if (UseLace)
  1403.       DrawImage(rp, &Pausebrush, 190, 150);
  1404.    else
  1405.       DrawImage(rp, &Pausebrush, 310, 85);
  1406.  
  1407.    while(!Done)
  1408.    {
  1409.       Wait(1L << window->UserPort->mp_SigBit);
  1410.  
  1411.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1412.          switch(imsg->Class) {
  1413.             case IDCMP_ACTIVEWINDOW:
  1414.                Done = TRUE;
  1415.                break;
  1416.  
  1417.             case IDCMP_REFRESHWINDOW:
  1418.                GT_BeginRefresh(window);
  1419.                GT_EndRefresh(window, TRUE);
  1420.                break;
  1421.          }
  1422.       }
  1423.    }
  1424.  
  1425.    if (UseLace)
  1426.       EraseImage(rp, &Pausebrush, 190,150);
  1427.    else
  1428.       EraseImage(rp, &Pausebrush, 310,85);
  1429.  
  1430.    for (line=1; line < YSIZE; line++) {
  1431.          for (column=1; column < XSIZE+1; column++)
  1432.             switch(field[line][column]) {
  1433.                case 0:
  1434.                   Draw_Box(rp, column, line, 0, FALSE);
  1435.                   break;
  1436.                case 1:
  1437.                   Draw_Box(rp, column, line, 1, TRUE);
  1438.                   break;
  1439.                case 2:
  1440.                   Draw_Box(rp, column, line, 2, TRUE);
  1441.                   break;
  1442.                case 3:
  1443.                   Draw_Box(rp, column, line, 3, TRUE);
  1444.                   break;
  1445.                case 4:
  1446.                   Draw_Box(rp, column, line, 4, TRUE);
  1447.                   break;
  1448.                case 5:
  1449.                   Draw_Box(rp, column, line, 5, TRUE);
  1450.                   break;
  1451.                case 6:
  1452.                   Draw_Box(rp, column, line, 6, TRUE);
  1453.                   break;
  1454.                case 7:
  1455.                   Draw_Box(rp, column, line, 7, TRUE);
  1456.                   break;
  1457.             }
  1458.    }
  1459. }
  1460.  
  1461.  
  1462.  
  1463. void UpdateStatistic(int objnumber)
  1464. {
  1465.    switch(objnumber) {
  1466.       case 0:
  1467.          obj1++;
  1468.          break;
  1469.       case 1:
  1470.          obj2++;
  1471.          break;
  1472.       case 2:
  1473.          obj3++;
  1474.          break;
  1475.       case 3:
  1476.          obj4++;
  1477.          break;
  1478.       case 4:
  1479.          obj5++;
  1480.          break;
  1481.       case 5:
  1482.          obj6++;
  1483.          break;
  1484.       case 6:
  1485.          obj7++;
  1486.          break;
  1487.    }
  1488. }
  1489.